//
//  LianliankanMapMaker.m
//  Lianliankan
//
//  Created by 李佳 on 15/3/15.
//  Copyright (c) 2015年 LiJia. All rights reserved.
//

#import "MapMaker.h"
#import "PosMatcher.h"
#import <UIKit/UIKit.h>

@implementation MapMaker

- (NSMutableArray*)RandomSortLLKMap: (NSMutableArray*)llkMap rows: (NSUInteger)rows andClos:(NSUInteger)clos //从一个一维数组中随机的获取
{
    NSMutableArray* resultArray = [[NSMutableArray alloc] init];
    
    //第一行0
    NSMutableArray* firstRow = [[NSMutableArray alloc] init];
    for (NSUInteger i = 0; i < clos + 2; ++i)
    {
        [firstRow addObject:[NSNumber numberWithInt:0]];
    }
    [resultArray addObject:firstRow];
    
    for (NSUInteger i = 0; i < rows; ++i)
    {
        NSMutableArray* rowsArray = [[NSMutableArray alloc] init];
        [rowsArray addObject:[NSNumber numberWithInt:0]];
        for (NSUInteger j = 0; j < clos; ++j)
        {
            int tempIndex = arc4random() % (llkMap.count);
            [rowsArray addObject:llkMap[tempIndex]];
            [llkMap removeObjectAtIndex:tempIndex];
        }
        [rowsArray addObject:[NSNumber numberWithInt:0]];
        [resultArray addObject:rowsArray];
    }
    //最后一行0
    NSMutableArray* lastRow = [[NSMutableArray alloc] init];
    for (NSUInteger i = 0; i < clos + 2; ++i)
    {
        [lastRow addObject:[NSNumber numberWithInt:0]];
    }
    [resultArray addObject:lastRow];
    
    return resultArray;
}

- (NSMutableArray*)ConfirmSolvabilityLLKMap: (NSMutableArray*)llkMap
{
    NSMutableArray* tmpPoints = [[NSMutableArray alloc] init];//存储还没有被移除的点。
    for (NSUInteger i = 1; i < llkMap.count - 1; ++i)
    {
        for (NSUInteger j = 1; j < ((NSArray*)llkMap[0]).count - 1; ++j)
        {
            [tmpPoints addObject:[NSValue valueWithCGPoint:CGPointMake(j, i)]];
        }
    }
    
    //所有点都置为0  不停的往里面插入点。
    NSMutableArray* resultArray = [[NSMutableArray alloc] init];
    for (NSUInteger i = 0; i < llkMap.count; ++i)
    {
        NSMutableArray* tmpArray = [[NSMutableArray alloc] init];
        for (NSUInteger j = 0; j < ((NSArray*)llkMap[0]).count; ++j)
        {
            [tmpArray addObject:[NSNumber numberWithInt:0]];
        }
        [resultArray addObject:tmpArray];
    }
    
    LLKPosMatcher* matcher = [[LLKPosMatcher alloc] init];
    matcher.LLKMapArray = [llkMap copy];
    
    NSUInteger matchIndex = 0;
    while (tmpPoints.count > 0)
    {
        NSValue* curValue = tmpPoints[matchIndex];
        CGPoint curPoint = [curValue CGPointValue];
        BOOL findMatchCase = NO;
        for (NSUInteger i = 0; i < tmpPoints.count; ++i)
        {
            //发现一个可以与当前进行匹配的
            NSValue* matchValue = tmpPoints[i];
            CGPoint matchPoint = [matchValue CGPointValue];
            if ([matcher LLKBtnMatchWithPoint:curPoint and:matchPoint])
            {
                resultArray[(int)curPoint.y][(int)curPoint.x] = llkMap[(int)curPoint.y][(int)curPoint.x];
                resultArray[(int)matchPoint.y][(int)matchPoint.x] = llkMap[(int)matchPoint.y][(int)matchPoint.x];
                //原来的两个点置0
                NSMutableArray* curRow = llkMap[(int)curPoint.y];
                curRow[(int)curPoint.x] = @0;
                
                NSMutableArray* matchRow = llkMap[(int)matchPoint.y];
                matchRow[(int)matchPoint.x] = @0;

                //将两个点从点阵中删除
                [tmpPoints removeObject:curValue];
                [tmpPoints removeObject:matchValue];
                
                findMatchCase = YES;
                break;
            }
        }
        
        if (findMatchCase)
        {
            //又从头开始找
            matchIndex = 0;
        }
        else
        {
            //继续一个 如果到最后都
            matchIndex++;
            if (matchIndex == tmpPoints.count) //那么出现锁死的情况 这个时候进行位置对换（随机的）重新开始一轮 知道解完
            {
                NSUInteger changePos = arc4random() % tmpPoints.count;
                //将第0个元素和 随机到的位置进行一个对换
                int firstData = [llkMap[(int)[tmpPoints[0] CGPointValue].y][(int)[tmpPoints[0] CGPointValue].x]intValue];
                int changeData = [llkMap[(int)[tmpPoints[changePos] CGPointValue].y][(int)[tmpPoints[changePos] CGPointValue].x] intValue];
                llkMap[(int)[tmpPoints[changePos] CGPointValue].y][(int)[tmpPoints[changePos] CGPointValue].x] = [NSNumber numberWithInt:firstData];
                llkMap[(int)[tmpPoints[0] CGPointValue].y][(int)[tmpPoints[0] CGPointValue].x] = [NSNumber numberWithInt:changeData];
                matchIndex = 0;
            }
        }
    }
    
    return resultArray;
}

- (NSMutableArray*)MakeLLKMapWithRow: (NSUInteger)rows Cloum: (NSUInteger)clos AndIndexCount: (NSUInteger)indexCount
{
    assert(rows * clos % 2 == 0);
    
    NSMutableArray* indexArr = [[NSMutableArray alloc] init];
    BOOL  isUserCycle = NO;
    if (rows * clos / 2 >= indexCount) //总数要比可用的多  先进行一轮循环。
    {
        for (int i = 0; i < indexCount; ++i)
        {
            [indexArr addObject:[NSNumber numberWithInt:i + 1]];
            [indexArr addObject:[NSNumber numberWithInt:i + 1]];
        }
        isUserCycle = YES;
    }
    NSUInteger i = 0 + (isUserCycle ? indexCount : 0);
    for ( ;i < rows * clos / 2; ++i)
    {
        int tmp = arc4random() % indexCount + 1;
        [indexArr addObject:[NSNumber numberWithInt:tmp]];
        [indexArr addObject:[NSNumber numberWithInt:tmp]];
    }
    
    indexArr = [self RandomSortLLKMap: indexArr rows:rows andClos:clos];
    return [self  ConfirmSolvabilityLLKMap:indexArr];
}

//判断地图是否有解

- (BOOL)isMapSolvability: (NSMutableArray*)llkMap
{
    
    NSMutableArray* tmpPoints = [[NSMutableArray alloc] init];//存储还没有被移除的点。
    for (NSUInteger i = 1; i < llkMap.count - 1; ++i)
    {
        for (NSUInteger j = 1; j < ((NSArray*)llkMap[0]).count - 1; ++j)
        {
            [tmpPoints addObject:[NSValue valueWithCGPoint:CGPointMake(j, i)]];
        }
    }
    
    //所有点都置为0  不停的往里面插入点。
    LLKPosMatcher* matcher = [[LLKPosMatcher alloc] init];
    matcher.LLKMapArray = [[NSMutableArray alloc] init];
    for (NSUInteger i = 0; i < llkMap.count; ++i)
    {
        NSMutableArray* tmpArray = [[NSMutableArray alloc] init];
        NSArray* rows = llkMap[i];
        for (NSUInteger j = 0; j < ((NSArray*)llkMap[0]).count; ++j)
        {
            [tmpArray addObject:[NSNumber numberWithInt:[rows[j] intValue]]];
        }
        [matcher.LLKMapArray addObject:tmpArray];
    }
    
    NSUInteger matchIndex = 0;
    while (tmpPoints.count > 0)
    {
        NSValue* curValue = tmpPoints[matchIndex];
        CGPoint curPoint = [curValue CGPointValue];
        BOOL findMatchCase = NO;
        for (NSUInteger i = 0; i < tmpPoints.count; ++i)
        {
            //发现一个可以与当前进行匹配的
            NSValue* matchValue = tmpPoints[i];
            CGPoint matchPoint = [matchValue CGPointValue];
            if ([matcher LLKBtnMatchWithPoint:curPoint and:matchPoint])
            {
                //原来的两个点置0
                NSMutableArray* curRow = matcher.LLKMapArray[(int)curPoint.y];
                curRow[(int)curPoint.x] = @0;
                
                NSMutableArray* matchRow = matcher.LLKMapArray[(int)matchPoint.y];
                matchRow[(int)matchPoint.x] = @0;
                
                //将两个点从点阵中删除
                [tmpPoints removeObject:curValue];
                [tmpPoints removeObject:matchValue];
                
                findMatchCase = YES;
                break;
            }
        }
        
        if (findMatchCase)
        {
            matchIndex = 0;//又从头开始找
        }
        else
        {
            matchIndex++;//继续一个 如果到最后都
            if (matchIndex == tmpPoints.count) //那么出现锁死的情况
                return NO;
        }
    }
    return YES;
}
- (void)randomResetLLKMap: (NSMutableArray*)llkMap
{
    NSMutableArray* tmpDataArr = [[NSMutableArray alloc] init];
    for (NSUInteger i = 1; i < llkMap.count - 1; ++i)
    {
        NSMutableArray* rowsArray = llkMap[i];
        for (NSUInteger j = 1; j < rowsArray.count - 1; ++j)
        {
            [tmpDataArr addObject:rowsArray[j]];
        }
    }
    
    for (NSUInteger i = 1; i < llkMap.count - 1; ++i)
    {
        NSMutableArray* rowsArray = llkMap[i];
        for (NSUInteger j = 1; j < rowsArray.count - 1; ++j)
        {
            int tempIndex = arc4random() % (tmpDataArr.count);
            rowsArray[j] = tmpDataArr[tempIndex];
            [tmpDataArr removeObjectAtIndex:tempIndex];
        }
    }
}

- (NSMutableArray*)resetLLKMap: (NSMutableArray*)llkMap
{
    [self randomResetLLKMap:llkMap];
    return [self  ConfirmSolvabilityLLKMap:llkMap];
}

- (BOOL)addRandomPair: (NSMutableArray*)llkMap WithTypeCount:(NSUInteger)indexCount
{
    NSMutableArray* tmpPoints = [[NSMutableArray alloc] init];//存储还没有被移除的点。
    for (NSUInteger i = 1; i < llkMap.count - 1; ++i)
    {
        NSMutableArray* rowsArray = llkMap[i];
        for (NSUInteger j = 1; j < rowsArray.count - 1; ++j)
        {
            if ([rowsArray[j] intValue] == 0)
                [tmpPoints addObject:[NSValue valueWithCGPoint:CGPointMake(j, i)]];
        }
    }
    if (tmpPoints.count == 0)
        return NO;
    //获取到了为0的两个点 然后random获取随意两个位置。
    do
    {
        int firstPos = arc4random() % (tmpPoints.count);
        int secondPos = firstPos;
        do
        {
            secondPos = arc4random() % (tmpPoints.count);
        }while (firstPos == secondPos);
        //随机队索引
        int index = arc4random() % indexCount + 1;
        CGPoint firstPoint = [tmpPoints[firstPos] CGPointValue];
        CGPoint secondPoint = [tmpPoints[secondPos] CGPointValue];
        llkMap[(int)firstPoint.y][(int)firstPoint.x] = [NSNumber numberWithInt:index];
        llkMap[(int)secondPoint.y][(int)secondPoint.x] = [NSNumber numberWithInt:index];
        if ([self isMapSolvability:llkMap])
            break;
        else
        {
            llkMap[(int)firstPoint.y][(int)firstPoint.x] = [NSNumber numberWithInt:0];
            llkMap[(int)secondPoint.y][(int)secondPoint.x] = [NSNumber numberWithInt:0];
        }
        
    }while (0);
    return YES;
}

- (NSArray*)removeOnePair: (NSMutableArray*)llkMap
{
    NSMutableArray* removePairArr = [[NSMutableArray alloc] init];
    
    NSMutableArray* tmpPoints = [[NSMutableArray alloc] init];//存储还没有被移除的点。
    for (NSUInteger i = 1; i < llkMap.count - 1; ++i)
    {
        NSMutableArray* rowsArray = llkMap[i];
        for (NSUInteger j = 1; j < rowsArray.count - 1; ++j)
        {
            if ([rowsArray[j] intValue] != 0)
                [tmpPoints addObject:[NSValue valueWithCGPoint:CGPointMake(j, i)]];
        }
    }
    if (tmpPoints.count == 0)
        return removePairArr;
    
    NSMutableArray* matchArr = [[NSMutableArray alloc] init];
    NSMutableArray* matchPathArr = [[NSMutableArray alloc] init];
    
    LLKPosMatcher* matcher = [[LLKPosMatcher alloc] init];
    matcher.LLKMapArray = llkMap;
    
    for (NSUInteger i = 0; i < tmpPoints.count; ++i)
    {
        CGPoint curPoint = [tmpPoints[i] CGPointValue];
        for (NSUInteger j = 0; j < tmpPoints.count; ++j)
        {
            CGPoint matchPoint = [tmpPoints[j] CGPointValue];
            NSArray* matchResult = [matcher LLKBtnMatchWithPoint:curPoint and:matchPoint];
            if (matchResult.count > 0) //找到解
            {
                NSDictionary* dic = @{@"firstPoint": [NSValue valueWithCGPoint:curPoint],
                                      @"secondPoint": [NSValue valueWithCGPoint:matchPoint]};
                [matchArr addObject:dic];
                [matchPathArr addObject:matchResult];
            }
        }
        
    }
    
    if (matchArr.count > 0)
    {
        NSUInteger index = arc4random() % matchArr.count;
        NSDictionary* result = matchArr[index];
        //同时移除掉源数据中的内容。
        CGPoint firstPoint = [result[@"firstPoint"] CGPointValue];
        CGPoint secondPoint = [result[@"secondPoint"] CGPointValue];
        llkMap[(int)firstPoint.y][(int)firstPoint.x] = [NSNumber numberWithInt:0];
        llkMap[(int)secondPoint.y][(int)secondPoint.x] = [NSNumber numberWithInt:0];
        
        //作为返回值
        removePairArr = matchPathArr[index];
    }
    return removePairArr;
}

@end
